import { projRoot } from './paths'

import type { ProjectManifest } from '@pnpm/types'

/**
 * 过滤不需要处理的文件
 * 该函数用于从给定的文件路径数组中筛选出需要进行进一步处理的文件路径它通过检查文件路径中是否包含特定的排除关键字来实现过滤
 * 主要用于排除项目中不需要进行某些操作（如打包、编译等）的目录或文件，例如 node_modules 目录，测试文件等
 * @param files 文件路径数组，代表待过滤的文件列表
 * @returns 过滤后的文件路径数组，不包含任何应被排除的文件路径
 */
export const excludeFiles = (files: string[]) => {
  // 定义需要排除的目录或文件的关键字
  const excludes = ['node_modules', 'test', 'mock', 'gulpfile', 'dist']

  // 过滤文件路径数组，排除包含特定关键字的路径
  return files.filter((path) => {
    // 确定路径判断的起始位置如果路径以 projRoot 开头，则从 projRoot 后的第一个字符开始判断
    const position = path.startsWith(projRoot) ? projRoot.length : 0

    // 确保排除关键字不在路径中出现，以避免对不需要处理的文件进行操作
    return !excludes.some((exclude) => path.includes(exclude, position))
  })
}

/**
 * 获取包的manifest信息
 * 该函数用于读取和解析指定路径下的包的manifest文件（如package.json）
 * 主要用于获取包的依赖信息等
 * @param pkgPath 包的路径，用于定位manifest文件
 * @returns 返回解析后的manifest对象
 */
export const getPackageManifest = (pkgPath: string) => {
  // eslint-disable-next-line @typescript-eslint/no-var-requires
  return require(pkgPath) as ProjectManifest
}

/**
 * 获取包的依赖关系
 * 该函数通过调用getPackageManifest函数获取包的manifest信息，
 * 然后提取并返回包的依赖项和对等依赖项
 * @param pkgPath 包的路径，用于定位manifest文件
 * @returns 返回一个记录了依赖项和对等依赖项名称的对象
 */
export const getPackageDependencies = (
  pkgPath: string
): Record<'dependencies' | 'peerDependencies', string[]> => {
  // 获取包的manifest信息
  const manifest = getPackageManifest(pkgPath)
  // 从manifest中解构出dependencies和peerDependencies，如果不存在则默认为空对象
  const { dependencies = {}, peerDependencies = {} } = manifest

  // 返回依赖项和对等依赖项的名称数组
  return {
    dependencies: Object.keys(dependencies),
    peerDependencies: Object.keys(peerDependencies),
  }
}
